package com.hang.jvm.risc;

public class Memory {

    private final byte[] memory;

    /**
     * 构造函数，初始化内存大小
     *
     * @param size 内存大小
     */
    public Memory(int size) {
        memory = new byte[size];
    }

    /**
     * 使用小端存储，一个word对应64位，8个字节，对应一个寄存器的大小 。
     * 内存中的地址从0开始，到size-1，所以要读一个word，需要从address开始读8个字节，
     * 然后将这8个字节按位或，得到一个64位的word。
     * memory | address | address+1 | address+2 | address+3 | address+4 | address+5 | address+6 | address+7 |
     * long   |        7|          6|          5|          4|          3|          2|          1|          0|
     *
     * @param address 要读的地址
     * @return 读取到的word
     */
    public long loadWord(long address) {
        return ((memory[(int) address] & 0xFFL) << 56) |
                ((memory[(int) address + 1] & 0xFFL) << 48) |
                ((memory[(int) address + 2] & 0xFFL) << 40) |
                ((memory[(int) address + 3] & 0xFFL) << 32) |
                ((memory[(int) address + 4] & 0xFFL) << 24) |
                ((memory[(int) address + 5] & 0xFFL) << 16) |
                ((memory[(int) address + 6] & 0xFFL) << 8) |
                (memory[(int) address + 7] & 0xFFL);
    }

    /**
     * 将value存储到address地址处，value为64位，8个字节，对应一个word。
     * 具体参考 loadWord(long)
     * memory | address | address+1 | address+2 | address+3 | address+4 | address+5 | address+6 | address+7 |
     * long   |        7|          6|          5|          4|          3|          2|          1|          0|
     *
     * @param address 要存储的地址
     * @param value   要存储的值
     */
    public void storeWord(long address, long value) {
        memory[(int) address] = (byte) (value >> 56);
        memory[(int) address + 1] = (byte) (value >> 48);
        memory[(int) address + 2] = (byte) (value >> 40);
        memory[(int) address + 3] = (byte) (value >> 32);
        memory[(int) address + 4] = (byte) (value >> 24);
        memory[(int) address + 5] = (byte) (value >> 16);
        memory[(int) address + 6] = (byte) (value >> 8);
        memory[(int) address + 7] = (byte) value;
    }
}
